package cevent.source.cloudcenter.server.service;

import cevent.source.cloudcenter.server.domain.Employee;
import cevent.source.cloudcenter.server.domain.EmployeeExample;
import cevent.source.cloudcenter.server.dto.*;
import cevent.source.cloudcenter.server.enums.EmployeeDepIdEnum;
import cevent.source.cloudcenter.server.enums.YesOrNoEnum;
import cevent.source.cloudcenter.server.exception.BusinessException;
import cevent.source.cloudcenter.server.exception.BusinessExceptionCode;
import cevent.source.cloudcenter.server.mapper.EmployeeMapper;
import cevent.source.cloudcenter.server.mapper.commonMapper.CommonEmployeeMapper;
import cevent.source.cloudcenter.server.util.DuplicateUtil;
import cevent.source.cloudcenter.server.util.UUID8Util;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;

/**
 * @author cevent
 * @description 员工管理表服务层
 */
@Service
public class EmployeeService {
    private static final Logger LOG = LoggerFactory.getLogger(EmployeeService.class);
    @Resource
    private EmployeeMapper employeeMapper;
    @Resource
    private CommonEmployeeMapper commonEmployeeMapper;

    //1.无分页列表查询：dto获取domain参数
    public List<EmployeeDto> employeeDtoList() {
        EmployeeExample employeeExample = new EmployeeExample();
        employeeExample.setOrderByClause("uni_id asc");
        List<Employee> employeeList = employeeMapper.selectByExample(employeeExample);
        List<EmployeeDto> employeeDtoList = new ArrayList<EmployeeDto>();
        for (int i = 0; i < employeeList.size(); i++) {
            Employee employee = employeeList.get(i);
            EmployeeDto employeeDto = new EmployeeDto();
            EmployeeWorkTimeDto workTimeDto=new EmployeeWorkTimeDto();
            if(!StringUtils.isEmpty(employee.getWorkTime())){
                try {
                    //将字符串转为jsonObj
                    JSONObject jsonWorkTime=JSON.parseObject(employee.getWorkTime());
                    //jsonObj转为javaObj
                    workTimeDto=JSONObject.toJavaObject(jsonWorkTime,EmployeeWorkTimeDto.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException(BusinessExceptionCode.EMP_WORK_TIME);
                }
            }
            //复制拷贝(source,target)
            BeanUtils.copyProperties(employee, employeeDto);
            employeeDto.setWorkTimeDto(workTimeDto);
            employeeDtoList.add(employeeDto);
        }
        return employeeDtoList;
    }

    //查询全部员工
    public List<EmployeeDto> allList() {
        EmployeeExample employeeExample = new EmployeeExample();
        employeeExample.setOrderByClause("uni_id asc");
        List<Employee> employees = employeeMapper.selectByExample(employeeExample);
        List<EmployeeDto> employeeDtos = DuplicateUtil.copyList(employees, EmployeeDto.class);
        return employeeDtos;
    }

    /*2.分页查询：pageDto保存数据
        list数据集合：listPageData
        当前页码：currentPage
        每页行数：size
        总计函数：totalSize
        前端可返回pageDto，无需返回值
     */
    public void getEmployeePageDtoList(PageDto pageDto) {
        //1.分页设置（前端传入当前页和每页行数params），起始页，每页行数size
        PageHelper.startPage(pageDto.getCurrentPage(), pageDto.getSize());

        EmployeeExample employeeExample = new EmployeeExample();
        employeeExample.setOrderByClause("dep_id asc");
        //包含longText，需要widthBlobs
        List<Employee> employeeList = employeeMapper.selectByExampleWithBLOBs(employeeExample);
        LOG.info("获取到的employeeList：{}", employeeList);
        //2.将mapper查询结果复制到pageInfo
        PageInfo<Employee> pageInfo = new PageInfo<>(employeeList);
        //3.pageInfo计算处理处理=>后分页的总行数set到pageDto做记录
        pageDto.setTotalSize(pageInfo.getTotal());

        List<EmployeeDto> employeeDtoList = new ArrayList<>();
        employeeList.stream().forEach(employee -> {
            EmployeeDto employeeDto = new EmployeeDto();
            EmployeeWorkTimeDto workTimeDto=new EmployeeWorkTimeDto();
            if(!StringUtils.isEmpty(employee.getWorkTime())){
                try {
                    //将字符串转为jsonObj
                    JSONObject jsonWorkTime=JSON.parseObject(employee.getWorkTime());
                    //jsonObj转为javaObj
                    workTimeDto=JSONObject.toJavaObject(jsonWorkTime,EmployeeWorkTimeDto.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException(BusinessExceptionCode.EMP_WORK_TIME);
                }
            }
            BeanUtils.copyProperties(employee, employeeDto);
            employeeDto.setWorkTimeDto(workTimeDto);
            employeeDtoList.add(employeeDto);
        });

        pageDto.setListPageData(employeeDtoList);

    }

    //3.新增、修改employee，将传入的id转为employee对象本身
    public void save(EmployeeDto employeeDto) {
        String workTime="";
        if(!StringUtils.isEmpty(employeeDto.getWorkTimeDto())){
            try {
                //将obj转为jsonObj
                JSONObject jsonWorkTime=(JSONObject)JSONObject.toJSON(employeeDto.getWorkTimeDto());
                workTime=jsonWorkTime.toJSONString();
                LOG.info("转换为jsonString的workTime：{}",workTime);
            } catch (Exception e) {
                e.printStackTrace();
                throw new BusinessException(BusinessExceptionCode.EMP_WORK_TIME);
            }
        }
        Employee employee = DuplicateUtil.copy(employeeDto, Employee.class);
        employee.setWorkTime(workTime);
        if (StringUtils.isEmpty(employeeDto.getUniId())) {
            this.insert(employee);
        } else {
            this.update(employee);
        }

    }

    //4.删除模块
    public void delete(String uniId) {
        EmployeeExample employeeExample = new EmployeeExample();
        employeeMapper.deleteByPrimaryKey(uniId);
    }

    //5.向外暴露dto，不暴露实体类：插入数据
    private void insert(Employee employee) {
        employee.setUniId(UUID8Util.getShortUUID());
        //查询login_name是否存在
        Employee empDB = DuplicateUtil.copy(this.getByLoginName(employee.getLoginName()), Employee.class);
        if (empDB != null) {
            throw new BusinessException(BusinessExceptionCode.EMP_LOGIN_NAME);
        }
        try {
            Date now = new Date();
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            long time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
            int timeInt = (int) (time / 1000);
            employee.setCreateTime(now);
            employee.setUpdateTime(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        employeeMapper.insert(employee);
    }

    //6.更新模块
    private void update(Employee employee) {
        try {
            Date now = new Date();
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            long time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
            int timeInt = (int) (time / 1000);

            employee.setUpdateTime(now);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //selective：根据传入的值进行更新，没有传入的列不进行更新，避免密码二次更新
        employee.setPassword(null);
        employeeMapper.updateByPrimaryKeySelective(employee);
    }

    //7.根据login_name查询是否存在
    public EmployeeDto getByLoginName(String loginName) {
        EmployeeExample employeeExample = new EmployeeExample();
        employeeExample.createCriteria().andLoginNameEqualTo(loginName);
        List<Employee> employees = employeeMapper.selectByExampleWithBLOBs(employeeExample);
        List<EmployeeDto> employeeDtos = DuplicateUtil.copyList(employees, EmployeeDto.class);
        //判断是否为空，不为空返回对象
        if (CollectionUtils.isEmpty(employeeDtos)) {
            return null;
        } else {
            return employeeDtos.get(0);
        }
    }

    //8.更新密码方法
    public EmployeeDto savePWD(EmployeeDto employeeDto) {
        //新建对象，只传入uniId和pwd
        Employee employee = new Employee();
        employee.setUniId(employeeDto.getUniId());
        employee.setPassword(employeeDto.getPassword());
        employeeMapper.updateByPrimaryKeySelective(employee);
        EmployeeDto emp = DuplicateUtil.copy(employee, EmployeeDto.class);
        return emp;
    }

    //9.登录用户查询
    public EmployeeLoginDto login(EmployeeDto employeeDto) {
        EmployeeDto emp = getByLoginName(employeeDto.getLoginName());
        //用户名不存在
        if (emp == null) {
            LOG.info("该用户名不存在：{}", employeeDto.getLoginName());
            //这里直接在ControllerExceptionHandler中配置了responseMsg
            throw new BusinessException(BusinessExceptionCode.EMP_LOGIN_NAME_ERROR);
        } else {
            //判断密码相等，登录成功
            if (emp.getPassword().equals(employeeDto.getPassword())) {
                //更新登录ip
                if (!employeeDto.getLoginIp().equals(emp.getLoginIp()) || emp.getLoginIp() == null) {
                    Employee employee = DuplicateUtil.copy(emp, Employee.class);
                    employee.setLoginIp(employeeDto.getLoginIp());
                    employeeMapper.updateByPrimaryKeySelective(employee);
                }
                EmployeeLoginDto employeeLoginDto=DuplicateUtil.copy(emp, EmployeeLoginDto.class);
                //将权限复制到loginDto
                setEmpAuthority(employeeLoginDto);
                //存入新loginDto中
                return employeeLoginDto;
            } else {
                //密码不对，返回前端
                LOG.info("密码不正确，输入密码：{} 原密码：{}", employeeDto.getPassword(), emp.getPassword());
                throw new BusinessException(BusinessExceptionCode.EMP_LOGIN_PWD_ERROR);
            }
        }
    }

    /**
     * 10.通过登录employeeId获取资源
     */
    private void setEmpAuthority(EmployeeLoginDto employeeLoginDto) {
        //根据employeeId获取资源信息
        List<ResourcesDto> resourcesDtos = commonEmployeeMapper.getEmpResourcesByEmpId(employeeLoginDto.getUniId());
        LOG.info("获取到的resourcesDto：{}",resourcesDtos);
        //将资源数组放入loginDto
        employeeLoginDto.setResourcesDtos(resourcesDtos);

        //遍历提取request
        HashSet<String> requestSet = new HashSet<>();
        if (!CollectionUtils.isEmpty(resourcesDtos)) {
            for (int i = 0; i < resourcesDtos.size(); i++) {
                ResourcesDto resourcesDto = resourcesDtos.get(i);
                String request=resourcesDto.getRequest();
                //JSON转换request
                List<String> requestList= JSON.parseArray(request,String.class);
                if(!CollectionUtils.isEmpty(requestList)){
                    //HashSet去重
                    requestSet.addAll(requestList);
                }
            }
        }
        LOG.info("用户获取的Authoryty权限：{}",requestSet);
        employeeLoginDto.setRequests(requestSet);
    }

    //获取客服及招商经理信息
    public List<EmployeeDto> getClientAttractInvestment(){
        EmployeeExample employeeExample=new EmployeeExample();
        EmployeeExample.Criteria criteria=employeeExample.createCriteria();
        List<String> showEmp=new ArrayList<>();
        showEmp.add(EmployeeDepIdEnum.DEP_ATTRACT.getCode());
        showEmp.add(EmployeeDepIdEnum.DEP_CLIENT_SERVICE.getCode());
        criteria.andDepIdIn(showEmp);
        criteria.andIsShowEqualTo(YesOrNoEnum.YES.getCode());
        List<Employee> employeeList=employeeMapper.selectByExampleWithBLOBs(employeeExample);
        LOG.info("获取到的客服：{}",employeeList);
        List<EmployeeDto> employeeDtoList=new ArrayList<>();
        employeeList.stream().forEach(employee -> {
            EmployeeDto employeeDto = new EmployeeDto();
            EmployeeWorkTimeDto workTimeDto=new EmployeeWorkTimeDto();
            if(!StringUtils.isEmpty(employee.getWorkTime())){
                try {
                    //将字符串转为jsonObj
                    JSONObject jsonWorkTime=JSON.parseObject(employee.getWorkTime());
                    //jsonObj转为javaObj
                    workTimeDto=JSONObject.toJavaObject(jsonWorkTime,EmployeeWorkTimeDto.class);
                } catch (Exception e) {
                    e.printStackTrace();
                    throw new BusinessException(BusinessExceptionCode.EMP_WORK_TIME);
                }
            }
            BeanUtils.copyProperties(employee, employeeDto);
            employeeDto.setPassword(null);
            employeeDto.setWorkTimeDto(workTimeDto);
            employeeDtoList.add(employeeDto);
        });
        LOG.info("转换后的客服：{}",employeeDtoList);
        return employeeDtoList;
    }
}
